package com.finch.juc;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Levi Wang
 * @create 2021-07-03 23:15
 */


//资源类,第一种写法，用传统的synchronized
//class Ticket{
//    private int number = 30;
//    public synchronized void saleTicket(){
//        if(number > 0){
//            System.out.println(Thread.currentThread().getName() + "\t卖出第：" + (number--)+"还剩下："+number);
//        }
//    }
//}







//资源类，第二种写法，用可重入锁ReentrantLock
class Ticket{
    private int number = 30;
    private Lock lock = new ReentrantLock();
    public void saleTicket(){

        lock.lock();
        try{
            if(number > 0){
                System.out.println(Thread.currentThread().getName() + "\t卖出第：" + (number--)+"还剩下："+number);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}





/**
 *
 * 题目L三个售票员 卖出 30张票
 *
 * 多线程编程的企业级套路 + 模板
 *
 * 1 在高内聚低耦合的前提下， 线程   操作（资源类中对外暴露的方法，因为是高内聚，所以最好操作最好写在资源类中）  资源类
 *
 *即：线程操作资源类
 *
 *
 */


public class SaleTicket {

    public static void main(String[] args) throws Exception{

        Ticket ticket = new Ticket();//资源类


//        //线程 + 操作  第一种写法， 匿名内部类
//        //Thread(Runnable target, String name)  Allocates a new Thread object.
//        //匿名内部类，new接口
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                for(int i = 0; i < 40; i++){//这里设为40是因为要保证能把票卖光
//                    ticket.saleTicket();
//                }
//            }
//        }, "A").start();
//        //上面就是一个称为A的线程；这里可以做成一个模板用快捷键调；但是目前最好还是自己写，熟悉熟悉
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                for(int i = 0; i < 40; i++){//这里设为40是因为要保证能把票卖光
//                    ticket.saleTicket();
//                }
//            }
//        }, "B").start();
//        //上面就是一个称为B的线程
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                for(int i = 0; i < 40; i++){//这里设为40是因为要保证能把票卖光
//                    ticket.saleTicket();
//                }
//            }
//        }, "C").start();
//        //上面就是一个称为C的线程





        //线程 + 操作  第二种写法，lambda表达式
        new Thread(() -> {for(int i = 0; i < 40; i++) ticket.saleTicket();},"A").start();
        new Thread(() -> {for(int i = 0; i < 40; i++) ticket.saleTicket();},"B").start();
        new Thread(() -> {for(int i = 0; i < 40; i++) ticket.saleTicket();},"C").start();


    }

}


























